/*
 * tim.c
 *
 *  Created on: Jul 2, 2020
 *      Author: HYJ
 */

#include "tim.h"

void TIM_Start(struct TIMER_COMMON *this) {
	HAL_TIM_Base_Start(&this->tim_handle);
}

void TIM_Stop(struct TIMER_COMMON *this) {
	HAL_TIM_Base_Stop(&this->tim_handle);
}

void TIM_StartIT(struct TIMER_COMMON *this) {
	HAL_TIM_Base_Start_IT(&this->tim_handle);
}

void TIM_StopIT(struct TIMER_COMMON *this) {
	HAL_TIM_Base_Stop_IT(&this->tim_handle);
}

u32 TIM_Get_CNT(struct TIMER_COMMON *this) {
	return __HAL_TIM_GET_COUNTER(&this->tim_handle);
}

void TIM_Set_CNT(struct TIMER_COMMON *this, u32 cnt) {
	__HAL_TIM_SET_COUNTER(&this->tim_handle, cnt);
}

void TIM_Set_ARR(struct TIMER_COMMON *this, u32 arr) {
	__HAL_TIM_SET_AUTORELOAD(&this->tim_handle, arr);
}

void TIM_Set_PSC(struct TIMER_COMMON *this, u32 psc) {
	__HAL_TIM_SET_PRESCALER(&this->tim_handle, psc);
}

void TIM_Set_PWM_Duty(struct PWM_COMMON *this, u32 compare) {
	__HAL_TIM_SET_COMPARE(&this->tim_handle, this->channel, compare);
}

void TIM_PWM_Start(struct PWM_COMMON *this) {
	HAL_TIM_PWM_Start(&this->tim_handle, this->channel);			//开启PWM通道
}

void TIM_PWM_Stop(struct PWM_COMMON *this) {
	HAL_TIM_PWM_Stop(&this->tim_handle, this->channel);				//关闭PWM通道
}

void TIM_IC_Start(struct IC_CAP_COMMON *this) {
	HAL_TIM_IC_Start(&this->tim_handle, this->channel);
}

void TIM_IC_Stop(struct IC_CAP_COMMON *this) {
	HAL_TIM_IC_Stop(&this->tim_handle, this->channel);
}

void TIM_IC_StartIT(struct IC_CAP_COMMON *this) {
	HAL_TIM_IC_Start_IT(&this->tim_handle, this->channel);
}

void TIM_IC_StopIT(struct IC_CAP_COMMON *this) {
	HAL_TIM_IC_Stop_IT(&this->tim_handle, this->channel);
}

void TIM_IC_Reset(struct IC_CAP_COMMON *this) {
//	TIM_RESET_CAPTUREPOLARITY(&this->tim_handle, this->channel);
}

u32 TIM_IC_Read_Capture_Value(struct IC_CAP_COMMON *this) {
	return HAL_TIM_ReadCapturedValue(&this->tim_handle, this->channel);
}

void TIM_IC_Set_Capture_Config(struct IC_CAP_COMMON *this, u32 mode) {
	TIM_SET_CAPTUREPOLARITY(&this->tim_handle, this->channel, mode);
}

void new_TIM_PWM_Channel(struct TIMER_COMMON *this, uint32_t Channel,
		GPIO_TypeDef *port, uint32_t pin) {

	GPIO_COMMON *output_pin = NULL;
	output_pin = new_Gpio(output_pin, port, pin, GPIO_MODE_AF_PP,
	GPIO_NOPULL,
	GPIO_SPEED_FREQ_HIGH);
	TIM_OC_InitTypeDef sConfigOC = { 0 };
	TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = { 0 };
	sConfigOC.OCMode = TIM_OCMODE_PWM1;
	sConfigOC.Pulse = 99;
	sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
	sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
	sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
	sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
	sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
	if (HAL_TIM_PWM_ConfigChannel(&this->tim_handle, &sConfigOC, Channel)
			!= HAL_OK) {
		Error_Handler();
	}

	sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
	sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
	sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
	sBreakDeadTimeConfig.DeadTime = 0;
	sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
	sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
	sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
	if (HAL_TIMEx_ConfigBreakDeadTime(&this->tim_handle, &sBreakDeadTimeConfig)
			!= HAL_OK) {
		Error_Handler();
	}

	this->pwm_out[Channel / 4].tim_handle = this->tim_handle;
	this->pwm_out[Channel / 4].channel = Channel;
	this->pwm_out[Channel / 4].Start = TIM_PWM_Start;
	this->pwm_out[Channel / 4].Stop = TIM_PWM_Stop;
	this->pwm_out[Channel / 4].SetDuty = TIM_Set_PWM_Duty;
}

void new_TIM_IC_CAPTURE_Channel(struct TIMER_COMMON *this, uint32_t Channel,
		GPIO_TypeDef *port, uint32_t pin) {

	GPIO_COMMON *cap_pin = NULL;
	cap_pin = new_Gpio(cap_pin, port, pin, GPIO_MODE_INPUT,
	GPIO_PULLDOWN,
	GPIO_SPEED_FREQ_HIGH);
	TIM_IC_InitTypeDef sConfigIC = { 0 };
	sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
	sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
	sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
	sConfigIC.ICFilter = 3;
	if (HAL_TIM_IC_ConfigChannel(&this->tim_handle, &sConfigIC, Channel)
			!= HAL_OK) {
		Error_Handler();
	}

	this->ic_cap[Channel / 4].tim_handle = this->tim_handle;
	this->ic_cap[Channel / 4].channel = Channel;
	this->ic_cap[Channel / 4].cap_sta = 0;
	this->ic_cap[Channel / 4].cap_value = 0;
	this->ic_cap[Channel / 4].Start = TIM_IC_Start;
	this->ic_cap[Channel / 4].Stop = TIM_IC_Stop;
	this->ic_cap[Channel / 4].StartIT = TIM_IC_StartIT;
	this->ic_cap[Channel / 4].StopIT = TIM_IC_StopIT;
	this->ic_cap[Channel / 4].Reset = TIM_IC_Reset;
	this->ic_cap[Channel / 4].ReadCapVal = TIM_IC_Read_Capture_Value;
	this->ic_cap[Channel / 4].SetConfig = TIM_IC_Set_Capture_Config;
}

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *tim_baseHandle) {

	if (tim_baseHandle->Instance == TIM1) {
		__HAL_RCC_TIM1_CLK_ENABLE();

		HAL_NVIC_SetPriority(TIM1_UP_IRQn, 1, 0);
		HAL_NVIC_EnableIRQ(TIM1_UP_IRQn);
	} else if (tim_baseHandle->Instance == TIM2) {
		__HAL_RCC_TIM2_CLK_ENABLE();

		HAL_NVIC_SetPriority(TIM2_IRQn, 1, 0);
		HAL_NVIC_EnableIRQ(TIM2_IRQn);
	} else if (tim_baseHandle->Instance == TIM3) {
		__HAL_RCC_TIM3_CLK_ENABLE();

		HAL_NVIC_SetPriority(TIM3_IRQn, 1, 0);
		HAL_NVIC_EnableIRQ(TIM3_IRQn);
	} else if (tim_baseHandle->Instance == TIM4) {
		__HAL_RCC_TIM4_CLK_ENABLE();

		HAL_NVIC_SetPriority(TIM4_IRQn, 1, 0);
		HAL_NVIC_EnableIRQ(TIM4_IRQn);
	}
}

void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *tim_baseHandle) {

	if (tim_baseHandle->Instance == TIM1) {
		__HAL_RCC_TIM1_CLK_DISABLE();

		HAL_NVIC_DisableIRQ(TIM1_UP_IRQn);
	} else if (tim_baseHandle->Instance == TIM2) {
		__HAL_RCC_TIM2_CLK_DISABLE();

		HAL_NVIC_DisableIRQ(TIM2_IRQn);
	} else if (tim_baseHandle->Instance == TIM3) {
		__HAL_RCC_TIM3_CLK_DISABLE();

		HAL_NVIC_DisableIRQ(TIM3_IRQn);
	} else if (tim_baseHandle->Instance == TIM4) {
		__HAL_RCC_TIM4_CLK_DISABLE();

		HAL_NVIC_DisableIRQ(TIM4_IRQn);
	}
}

TIMER_COMMON* new_TIMER(struct TIMER_COMMON *this, TIM_TypeDef *tim, u8 mode,
		u32 psc, u32 arr) {
	TIM_ClockConfigTypeDef sClockSourceConfig = { 0 };
	TIM_MasterConfigTypeDef sMasterConfig = { 0 };
	this = (struct TIMER_COMMON*) calloc(1, sizeof(struct TIMER_COMMON));
	this->tim_handle.Instance = tim;
	this->tim_handle.Init.Prescaler = psc;
	this->tim_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
	this->tim_handle.Init.Period = arr;
	this->tim_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
	this->tim_handle.Init.RepetitionCounter = 0;
	this->tim_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

	if (HAL_TIM_Base_Init(&this->tim_handle) != HAL_OK) {
		Error_Handler();
	}
	sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
	if (HAL_TIM_ConfigClockSource(&this->tim_handle, &sClockSourceConfig)
			!= HAL_OK) {
		Error_Handler();
	}
	if (mode == PWM_MODE) {
		if (HAL_TIM_PWM_Init(&this->tim_handle) != HAL_OK) {
			Error_Handler();
		}
	} else if (mode == IC_CAPTURE_MODE) {
		if (HAL_TIM_IC_Init(&this->tim_handle) != HAL_OK) {
			Error_Handler();
		}
	}
	sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
	sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
	if (HAL_TIMEx_MasterConfigSynchronization(&this->tim_handle, &sMasterConfig)
			!= HAL_OK) {
		Error_Handler();
	}
	this->StopIT = TIM_StopIT;
	this->StartIT = TIM_StartIT;
	this->Stop = TIM_Stop;
	this->Start = TIM_Start;
	this->GetCNT = TIM_Get_CNT;
	this->SetCNT = TIM_Set_CNT;
	this->SetARR = TIM_Set_ARR;
	this->SetPSC = TIM_Set_PSC;
	this->AddPWMCh = new_TIM_PWM_Channel;
	this->AddICAPCh = new_TIM_IC_CAPTURE_Channel;
	return this;
}
